package com.yuyou.fn.analyze.service.impl;

import com.github.wens.mybatisplus.plugins.Page;
import com.yuyou.fn.analyze.service.IRefundStatisticsService;
import com.yuyou.fn.analyze.vo.RefundDetailVo;
import com.yuyou.fn.analyze.vo.RefundSituationVo;
import com.yuyou.fn.analyze.vo.SumRefundSituation;
import com.yuyou.fn.common.util.BeanUtils;
import com.yuyou.fn.common.util.Utils;
import com.yuyou.fn.educational.entity.StudentRefund;
import com.yuyou.fn.educational.service.IStudentRefundService;
import com.yuyou.fn.educational.service.IStudentRegService;
import com.yuyou.fn.educational.vo.PeriodBusTeamGradeRefundAmountVo;
import com.yuyou.fn.educational.vo.StudentRefundQueryVo;
import com.yuyou.fn.educational.vo.SumRefundVo;
import com.yuyou.fn.platform.permission.DataPermission;
import com.yuyou.fn.report.entity.MergeStudentRegDetail;
import com.yuyou.fn.report.entity.StudentRegDetail;
import com.yuyou.fn.report.service.IMergeStudentRegDetailService;
import com.yuyou.fn.report.service.IStudentRegDetailService;
import com.yuyou.fn.report.vo.PeriodBusTeamGradeRegVo;
import com.yuyou.fn.report.vo.StudentRegDetailQueryVo;
import com.yuyou.fn.report.vo.SumRegVo;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 *
 * ProductTarget 表数据服务层接口实现类
 *
 */
@Service
public class RefundStatistsServiceImpl implements IRefundStatisticsService {

    @Resource
    private IMergeStudentRegDetailService mergeStudentRegDetailService;

    @Resource
    private IStudentRegDetailService studentRegDetailService;

    @Resource
    private IStudentRefundService studentRefundService;

    @Override
    public Page<RefundDetailVo> findRefundDetail(DataPermission dataPermission, StudentRefundQueryVo studentRefundQueryVo, int pageNo, int pageSize) {
        studentRefundQueryVo.setStatus(1);
        Page<StudentRefund> studentRefundPage=studentRefundService.findStudentRefundList(studentRefundQueryVo,dataPermission,pageNo,pageSize);
        Page<RefundDetailVo> refundDetailVoPage=Utils.newPage(studentRefundPage);
        List<StudentRefund> studentRefundList=studentRefundPage.getRecords();
        List<Long> studentRegIds = BeanUtils.toList(studentRefundList, "studentRegId");
        studentRegIds=Utils.removeDuplicate(studentRegIds);
        List<StudentRegDetail> studentRegDetailList =null;
        if (studentRegIds.size()>0){
            studentRegDetailList =studentRegDetailService.findByIds(studentRegIds);
            Map<Long,StudentRegDetail> map=BeanUtils.toMap(studentRegDetailList,"regId");
            List<RefundDetailVo> refundDetailVoList=new ArrayList<>(studentRefundList.size());
            for (StudentRefund studentRefund:studentRefundList){
                RefundDetailVo refundDetailVo=new RefundDetailVo();
                StudentRegDetail studentRegDetail =map.get(studentRefund.getStudentRegId());
                if (studentRegDetail ==null){
                    continue;
                }
                BeanUtils.copyProperties(refundDetailVo, studentRegDetail);
                refundDetailVo.setStudentRefundId(studentRefund.getStudentRefundId());
                refundDetailVo.setRealAmount(studentRegDetail.getPayAmount().subtract(studentRegDetail.getRefundAmount()==null? BigDecimal.ZERO: studentRegDetail.getRefundAmount()));
                refundDetailVo.setRefundAmount(studentRefund.getAmount());
                refundDetailVo.setRefundWay(studentRefund.getRefundWay());
                refundDetailVo.setApplyOperator(studentRefund.getApplyOperator());
                refundDetailVo.setApplyTime(studentRefund.getCreateTime());
                int num= studentRegDetail.getEndAmount()- studentRegDetail.getStartAmount()+1;
                refundDetailVo.setReadingLectureNum(num<0?0:num);
                if (studentRegDetail.getStartAmount()==0 && studentRegDetail.getEndAmount()==0){
                    refundDetailVo.setReadingLectureNum(0);
                }
                refundDetailVo.setReadingLectureNos(studentRegDetail.getStartAmount()+"-"+ studentRegDetail.getEndAmount());
                refundDetailVo.setRefundLectureNum(StringUtils.isEmpty(studentRefund.getRefundLecture())?0:studentRefund.getRefundLecture().split(",").length);
                refundDetailVo.setRefundLectureNos(studentRefund.getRefundLecture());
                refundDetailVo.setRefundReason(studentRefund.getDescription());
                refundDetailVoList.add(refundDetailVo);

            }
            refundDetailVoPage.setRecords(refundDetailVoList);
        }

        return refundDetailVoPage;
    }

    @Override
    public SXSSFWorkbook exportRefundDetail(DataPermission dataPermission, StudentRefundQueryVo studentRefundQueryVo) {
        Page<RefundDetailVo> refundDetailVoPage = this.findRefundDetail(dataPermission, studentRefundQueryVo, 1, 30000);
        return refundDetail2excel(refundDetailVoPage.getRecords());
    }

    public static SXSSFWorkbook refundDetail2excel(List<RefundDetailVo> refundDetailVoList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("退费明细");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "期数", "业务组", "年级","科目","姓名","学号","电话","生源类型", "报读班级", "报名校区", "应缴金额", "实缴金额", "实退金额","退费方式","退费申请人","申请退费时间","在读讲数","退费讲数","退费讲次","退费原因"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;
        Map<Integer,String> studentStateMap=new HashMap<>();
        studentStateMap.put(0,"新生");
        studentStateMap.put(1,"老生");
        studentStateMap.put(2,"续读生");
        Map<Integer,String> refundWayMap=new HashMap<>();
        refundWayMap.put(0 ,"支付宝");
        refundWayMap.put(1 ,"微信");
        refundWayMap.put(2 ,"现金");
        refundWayMap.put(3 ,"虚拟余额账户");
        refundWayMap.put(4 ,"银行卡转账");

        if (refundDetailVoList!=null){
            for (RefundDetailVo refundDetailVo : refundDetailVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getPeriodName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getBusTeamName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getGradeName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getSubjectName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getStudentName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getStudentNo()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getStudentPhoneNo()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(studentStateMap.get(refundDetailVo.getStudentState())==null?"":studentStateMap.get(refundDetailVo.getStudentState()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getClassName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getCampusName()));

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundDetailVo.getTotalAmount()==null?0d:refundDetailVo.getTotalAmount().doubleValue());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundDetailVo.getRealAmount()==null?0d:refundDetailVo.getRealAmount().doubleValue());


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundDetailVo.getRefundAmount()==null?0d:refundDetailVo.getRefundAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellValue(refundDetailVo.getRefundWay()==null?"":refundWayMap.get(refundDetailVo.getRefundWay()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getApplyOperator()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(refundDetailVo.getApplyTime()==null?"":Utils.formatDate(refundDetailVo.getApplyTime(),"yyyy-MM-dd HH:mm:ss"));

                cell = row.createCell(cellNum++);
                cell.setCellValue(refundDetailVo.getReadingLectureNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(refundDetailVo.getRefundLectureNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getRefundLectureNos()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundDetailVo.getRefundReason()));

            }
        }
        return excel;
    }


    @Override
    public Page<RefundSituationVo> findRefundSituation(DataPermission dataPermission,StudentRegDetailQueryVo studentRegDetailQueryVo, Integer refundWay,int pageNo,int pageSize) {

        Page<PeriodBusTeamGradeRegVo> periodBusTeamGradeRegVoPage=mergeStudentRegDetailService.findRegSituationPage(dataPermission,studentRegDetailQueryVo,pageNo,pageSize);
        Page<RefundSituationVo> refundSituationVoPage=Utils.newPage(periodBusTeamGradeRegVoPage);
        List<PeriodBusTeamGradeRegVo> periodBusTeamGradeRegVos=periodBusTeamGradeRegVoPage.getRecords();
        StudentRefundQueryVo studentRefundQueryVo=new StudentRefundQueryVo();
        BeanUtils.copyProperties(studentRefundQueryVo,studentRegDetailQueryVo);
        studentRefundQueryVo.setRefundWay(refundWay);
        List<PeriodBusTeamGradeRefundAmountVo> periodBusTeamGradeRefundAmountVos=studentRefundService.findPeriodBusTeamGradeRefundAmount(studentRefundQueryVo);
        Map<String,PeriodBusTeamGradeRefundAmountVo> refundMap=new HashMap<>();

        for (PeriodBusTeamGradeRefundAmountVo periodBusTeamGradeRefundAmountVo:periodBusTeamGradeRefundAmountVos){
            String key=periodBusTeamGradeRefundAmountVo.getPeriodId()+"_"+periodBusTeamGradeRefundAmountVo.getBusTeamId()+"_"+periodBusTeamGradeRefundAmountVo.getGradeId();
            PeriodBusTeamGradeRefundAmountVo onePeriodBusTeamGradeRefundAmountVo=refundMap.get(key);
            if (onePeriodBusTeamGradeRefundAmountVo==null){
                onePeriodBusTeamGradeRefundAmountVo=periodBusTeamGradeRefundAmountVo;
                refundMap.put(key,onePeriodBusTeamGradeRefundAmountVo);
            }
        }
        if (periodBusTeamGradeRegVos!=null){
            List<RefundSituationVo> refundSituationVoList=new ArrayList<>();
            for (PeriodBusTeamGradeRegVo periodBusTeamGradeRegVo:periodBusTeamGradeRegVos){
                String key=periodBusTeamGradeRegVo.getPeriodId()+"_"+periodBusTeamGradeRegVo.getBusTeamId()+"_"+periodBusTeamGradeRegVo.getGradeId();
                RefundSituationVo refundSituationVo=new RefundSituationVo();
                BeanUtils.copyProperties(refundSituationVo,periodBusTeamGradeRegVo);

                PeriodBusTeamGradeRefundAmountVo periodBusTeamGradeRefundAmountVo=refundMap.get(key);
                if (periodBusTeamGradeRefundAmountVo!=null){
                    refundSituationVo.setRefundPersonNum(periodBusTeamGradeRefundAmountVo.getRefundPersonNum());
                    refundSituationVo.setRefundBranchNum(periodBusTeamGradeRefundAmountVo.getRefundBranchNum());
                    refundSituationVo.setRefundAmount(periodBusTeamGradeRefundAmountVo.getRefundAmount());
                }
                refundSituationVo.setPersonRefundRate(Utils.getPercent(refundSituationVo.getRefundPersonNum().toString(),refundSituationVo.getRegPersonNum().toString(),2));
                refundSituationVo.setBranchRefundRate(Utils.getPercent(refundSituationVo.getRefundBranchNum().toString(),refundSituationVo.getRegBranchNum().toString(),2));
                refundSituationVoList.add(refundSituationVo);
            }
            refundSituationVoPage.setRecords(refundSituationVoList);
        }

        return refundSituationVoPage;
    }

    @Override
    public SumRefundSituation findSumRefundSituation(DataPermission dataPermission, StudentRegDetailQueryVo studentRegDetailQueryVo, Integer refundWay) {
        SumRegVo sumRegVo=mergeStudentRegDetailService.findSumReg(dataPermission,studentRegDetailQueryVo);
        StudentRefundQueryVo studentRefundQueryVo=new StudentRefundQueryVo();
        BeanUtils.copyProperties(studentRefundQueryVo,studentRegDetailQueryVo);
        studentRefundQueryVo.setRefundWay(refundWay);
        SumRefundVo sumRefundVo=studentRefundService.findSumRefund(studentRefundQueryVo);
        SumRefundSituation sumRefundSituation=new SumRefundSituation();
        BeanUtils.copyProperties(sumRefundSituation,sumRegVo);
        BeanUtils.copyProperties(sumRefundSituation,sumRefundVo);
        sumRefundSituation.setPersonRefundRate(Utils.getPercent(sumRefundSituation.getRefundPersonNum().toString(),sumRefundSituation.getRegPersonNum().toString(),2));
        sumRefundSituation.setBranchRefundRate(Utils.getPercent(sumRefundSituation.getRefundBranchNum().toString(),sumRefundSituation.getRegBranchNum().toString(),2));


        return sumRefundSituation;
    }

    @Override
    public SXSSFWorkbook exportRefundSituation(DataPermission dataPermission, StudentRegDetailQueryVo studentRegDetailQueryVo, Integer refundWay) {
        Page<RefundSituationVo> refundSituation = this.findRefundSituation(dataPermission, studentRegDetailQueryVo, refundWay, 1, 20000);
        return refundSituation2excel(refundSituation.getRecords());
    }

    public static SXSSFWorkbook refundSituation2excel(List<RefundSituationVo> refundSituationVoList) {

        SXSSFWorkbook excel = new SXSSFWorkbook();
        SXSSFSheet sheet = excel.createSheet("退费概况");
        SXSSFRow firstRow = sheet.createRow(0);
        String[] titles = new String[]{ "期数", "业务组", "年级","实收金额", "退费金额", "报读人数", "退费人数", "人数退费率", "报名科数","退费科数","科数退费率"};
        for (int i = 0; i < titles.length; i++) {
            firstRow.createCell(i).setCellValue(titles[i]);
        }
        int rowNum = 1;

        if (refundSituationVoList!=null){
            for (RefundSituationVo refundSituationVo : refundSituationVoList) {
                int cellNum = 0;

                SXSSFRow row = sheet.createRow(rowNum++);

                SXSSFCell cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundSituationVo.getPeriodName()));


                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundSituationVo.getBusTeamName()));

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundSituationVo.getGradeName()));

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRealAmount()==null?0d:refundSituationVo.getRealAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRefundAmount()==null?0d:refundSituationVo.getRefundAmount().doubleValue());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRegPersonNum()==null?0:refundSituationVo.getRegPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRefundPersonNum()==null?0:refundSituationVo.getRefundPersonNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundSituationVo.getPersonRefundRate()));


                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRegBranchNum()==null?0:refundSituationVo.getRegBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellType(CellType.NUMERIC);
                cell.setCellValue(refundSituationVo.getRefundBranchNum()==null?0:refundSituationVo.getRefundBranchNum());

                cell = row.createCell(cellNum++);
                cell.setCellValue(StringUtils.defaultString(refundSituationVo.getBranchRefundRate()));

            }
        }
        return excel;
    }

}